package cn.edu.sgu.www.mhxysy.shiro;

import cn.edu.sgu.www.mhxysy.consts.RedisKeyPrefixes;
import cn.edu.sgu.www.mhxysy.entity.system.User;
import cn.edu.sgu.www.mhxysy.feign.clients.pms.PmsFeignService;
import cn.edu.sgu.www.mhxysy.restful.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author 沐雨橙风ιε
 * @version 1.0
 */
@Slf4j
public class UsernameRealm extends AuthorizingRealm {

	/**
	 * 服务名
	 */
	@Value("${spring.application.name}")
	private String service;

	@Autowired
	private PmsFeignService feignService;

	/**
	 * 登录认证
	 */
	@Override
	public SimpleAuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) {
		// 得到令牌
		UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
		
		// 从token中获取用户名
		String username = token.getUsername();

		// 根据用户名查询用户信息
		JsonResult<User> jsonResult = feignService.selectByUsername(username, service);

		if (jsonResult.isSuccess()) {
			User user = jsonResult.getData();

			if (user == null) {
				throw new AuthenticationException("登录失败，用户名不存在~");
			}

			return new SimpleAuthenticationInfo(user, user.getPassword(), username);
		} else {
			throw new AuthenticationException(jsonResult.getMessage());
		}
	}

	/**
	 * 用户授权
	 */
	@Override
	public SimpleAuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		// 获取登录的用户信息
		User user = (User) principals.getPrimaryPrincipal();
		// 得到用户名
		String username = user.getUsername();
		List<String> list = null;

		// 查询用户的权限
		JsonResult<List<String>> jsonResult = feignService.selectUserPermissions(username, service);

		if (jsonResult.isSuccess()) {
			list = jsonResult.getData();
		}

		// 构建返回值对象
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

		if (list != null) {
			Set<String> permissions = new HashSet<>(list);

			authorizationInfo.setStringPermissions(permissions);
		}

		// 查询用户的角色列表
		JsonResult<Set<String>> result = feignService.selectUserRoles(username, service);

		if (result.isSuccess()) {
			Set<String> roles = result.getData();

			authorizationInfo.setRoles(roles);
		}

		return authorizationInfo;
	}

	/**
	 * 配置授权缓存的key
	 * @param principals PrincipalCollection
	 * @return String
	 */
	@Override
	public String getAuthorizationCacheKey(PrincipalCollection principals) {
		// 获取登录的用户信息
		Object principal = principals.getPrimaryPrincipal();

		if (principal instanceof User) {
			// 得到用户名
			User user = (User) principal;
			String username = user.getUsername();

			return RedisKeyPrefixes.PREFIX_CACHE_AUTHORIZATION + username;
		}

		return null;
	}

}